using net_work.Common.Request;
using Newtonsoft.Json;
using StackExchange.Redis;

namespace net_work.Common;

public interface ITaskQueue
{
    /// <summary>
    /// 添加任务
    /// </summary>
    /// <param name="task">任务</param>
    Task EnqueueAsync(TaskRequest task);

    /// <summary>
    /// 获取任务
    /// </summary>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>任务</returns>
    Task<TaskRequest?> DequeueAsync(CancellationToken cancellationToken);
}

public class RedisTaskQueue(IConnectionMultiplexer redis) : ITaskQueue
{
    private readonly IDatabase _database = redis.GetDatabase();
    private const string QueueName = "TaskQueue";
    private readonly SemaphoreSlim _semaphore = new(0); // 初始信号量为 0

    // 将任务添加到 Redis 队列
    public async Task EnqueueAsync(TaskRequest task)
    {
        var serializedTask = JsonConvert.SerializeObject(task);
        await _database.ListLeftPushAsync(QueueName, serializedTask); // 使用 LPUSH 将任务推入队列
        _semaphore.Release(); // 释放信号，通知消费者队列中有任务
    }

    // 从 Redis 队列中获取任务
    public async Task<TaskRequest?> DequeueAsync(CancellationToken cancellationToken)
    {
        while (!cancellationToken.IsCancellationRequested)
        {
            // 等待信号量（有任务时继续）
            await _semaphore.WaitAsync(cancellationToken);

            // 使用 Redis 的 BRPOP 阻塞获取队列中的任务，超时为 0 表示无限阻塞
            var result = await _database.ListRightPopAsync(QueueName);
            if (result.IsNull)
            {
                return null;
            }

            var task = JsonConvert.DeserializeObject<TaskRequest>(result.ToString());
            return task;
        }

        return null; // 如果取消则返回 null
    }
}